using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Web.Services.Protocols;
using PeoplesJukebox.Core.Logging;

namespace PeoplesJukebox.Services.ServiceModel.ErrorHandlers
{
    /// <summary>
    /// Error handler to log all unhandled exceptions 
    /// </summary>
    public class LogErrorHandler : IErrorHandler
    {
        private string ServiceName
        {
            get
            {
                string serviceName;
                try
                {
                    serviceName = OperationContext.Current.RequestContext.RequestMessage.Headers.Action;
                }
                catch
                {
                    serviceName = "<Unknown>";
                }
                return serviceName;
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public LogErrorHandler() { }

        /// <summary>
        /// Logs all unhandled exceptions as errors
        /// </summary>
        /// <param name="error">Unhandled exception</param>
        /// <returns>Whether exception was handled</returns>
        public bool HandleError(Exception error)
        {
            Log.Error("Service: {0}, uncaught exception: {1}", this.ServiceName, error.Message);
            return true;
        }

        /// <summary>
        /// Builds a fault message for WCF to return to the caller
        /// </summary>
        /// <param name="error">Unhandled exception</param>
        /// <param name="version">Message version</param>
        /// <param name="fault">Fault message</param>
        public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
        {
            //build undeclared SOAP fault:
            FaultException ex = new FaultException(error.Message, FaultCode.CreateSenderFaultCode(SoapException.ServerFaultCode.Name, SoapException.ServerFaultCode.Namespace));
            MessageFault messageFault = ex.CreateMessageFault();
            fault = Message.CreateMessage(version, messageFault, this.ServiceName);
        }
    }
}
